﻿using System;
using System.Collections.Generic;
using System.Text;
using ITAP.ShprossesBuilder.Modelling;
using ITAP.ShprossesBuilder.Modelling.Components;
using ITAP.ShprossesBuilder.Calculations;
using ITAP.Core.Modelling;
using ITAP.Core.Calculations;

namespace ITAP.ShprossesBuilder.Manipulation
{
    public class CommandCreateShprossesOnShprossConnector : SerializedUndoRedo, ICommand, IModelVisitor
    {
        private Shpross shprossPrototype;
        private double shprossLength;

        public CommandCreateShprossesOnShprossConnector(ModelControl modelControl, Shpross shprossPrototype, double shprossLength)
        {
            this.modelControl = modelControl;
            this.shprossPrototype = shprossPrototype;
            this.shprossLength = shprossLength;
        }

        #region ICommand Members

        public void StartExecute()
        {
            this.undoModelContainer = (ModelContainer)modelControl.ModelContainer.Clone();
            modelControl.ModelContainer.AcceptVisitor(this);           
        }

        public void Execute()
        {
        }

        public void EndExecute()
        {
        }

        public bool IsNeedModelUpdate
        {
            get { return true; }
        }

        public string Name
        {
            get { return "Создать профили на соединителе"; }
        }

        #endregion

        #region ICloneable Members

        public object Clone()
        {
            CommandCreateShprossesOnShprossConnector clone = new CommandCreateShprossesOnShprossConnector(modelControl, shprossPrototype, shprossLength);
            if (this.undoModelContainer != null)
                clone.undoModelContainer = (ModelContainer)this.undoModelContainer.Clone();
            if (this.redoModelContainer != null)
                clone.redoModelContainer = (ModelContainer)this.redoModelContainer.Clone();
            return clone;
        }

        #endregion

        #region IModelVisitor Members

        public void Visit(ITAP.ShprossesBuilder.Modelling.Components.Model model)
        {
         //   throw new NotImplementedException();
        }

        public void Visit(ITAP.ShprossesBuilder.Modelling.Components.Connector connector)
        {
          //  throw new NotImplementedException();
        }

        public void Visit(ITAP.ShprossesBuilder.Modelling.Components.Shpross shpross)
        {
          //  throw new NotImplementedException();
        }

        public void Visit(ITAP.ShprossesBuilder.Modelling.Components.Spacer spacer)
        {
          //  throw new NotImplementedException();
        }

        public void Visit(ITAP.ShprossesBuilder.Modelling.Components.ShprossConnectorStub stub)
        {
          //  throw new NotImplementedException();
        }

        public void Visit(ITAP.ShprossesBuilder.Modelling.Components.ShprossConnector shprossConnector)
        {
            if (shprossConnector.Selected)
            {
                Model model = (Model)shprossConnector.Parent;
                foreach (IComponent innerComponent in shprossConnector.InnerComponents)
                {
                    if (innerComponent is Connector)
                    {
                        Connector connector = innerComponent as Connector;

                        if (connector.EndConnectedComponent != null)
                            continue;

                        ModelVector tangent = connector.Primitives[0].GetTangent(0);
                        tangent = tangent.Multiply(shprossLength);
                        ModelPoint endPoint = ModelCalculations.GetOffsetPoint(connector.StartPoint, tangent);
                        Shpross shpross = (Shpross)shprossPrototype.Clone();
                        shpross.MoveStartPointTo(connector.StartPoint);
                        shpross.MoveEndPointTo(endPoint);
                        model.AddInnerComponent(shpross);
                    }
                }
            }
        }

        public void Visit(ITAP.ShprossesBuilder.Modelling.Components.SpacerElement spacerElement)
        {
          //  throw new NotImplementedException();
        }

        public void Visit(ITAP.ShprossesBuilder.Modelling.Components.SpacerConnector spacerConnector)
        {
           // throw new NotImplementedException();
        }

        public void Visit(ITAP.ShprossesBuilder.Modelling.Components.ModelCell modelCell)
        {
            //throw new NotImplementedException();
        }

        public void Visit(ITAP.ShprossesBuilder.Modelling.Components.ModelContainer modelContainer)
        {
            foreach (IComponent innerComponent in modelContainer.AllInnerComponents)
            {
                innerComponent.AcceptVisitor(this);
            }
        }

        public void Visit(ITAP.ShprossesBuilder.Modelling.Components.StickConnector stickConnector)
        {
          //  throw new NotImplementedException();
        }

        public void Visit(ITAP.ShprossesBuilder.Modelling.Components.SnapOnCap snapOnCap)
        {
         //   throw new NotImplementedException();
        }

        #endregion

        #region IModelVisitor Members


        public void Visit(ShprossEndToEndConnector endToEndConnector)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IModelVisitor Members


        public void Visit(ShprossChain shprossChain)
        {
       //     throw new NotImplementedException();
        }

        #endregion

        #region IModelVisitor Members


        public void Visit(SpacerContainer spacerContainer)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IModelVisitor Members


        public void Visit(CrossConnector crossConnector)
        {
    //        throw new NotImplementedException();
        }

        #endregion
        public override string ToString()
        {
            return this.Name;
        }

        #region ICommand Members



        private bool enabled = true;
        public bool Enabled
        {
            get
            {
                return enabled;
            }
            set
            {
                enabled = value;
            }
        }
        #endregion

        #region ICommand Members


        public bool IsNeedVisitorsUpdate
        {
            get { return true; }
        }

        #endregion
    }
}
